{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit MediateServer;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, ActiveX, Classes, ComObj, mediate_TLB, StdVcl;

type
  TMediateServer = class(TInterfacedObject, IMediateServer, IMediateInternet, IMediateApplication)
  private
    FInternalName: String;
  protected
    {Declare IMediateServer methods here}
    function GetAPIVersion(out Version: WideString): HResult; stdcall;
    function GetConfigDirectory(out Directory: WideString): HResult; stdcall;
    function GetThemeDirectory(out Directory: WideString): HResult; stdcall;
    function SubscribeEvent(const Event: WideString): HResult; stdcall;
    function UnsubscribeEvent(const Event: WideString): HResult; stdcall;
    function GetMetaData(const Name: WideString; out Value: WideString): HResult; stdcall;
    function SetMetaData(const Name: WideString; const Value: WideString): HResult; stdcall;
    function ClearMetaData(const Name: WideString): HResult; stdcall;
    function GetLanguageText(const Name: WideString; out LanguageText: WideString): HResult; stdcall;
    function CallFunction(const Name: WideString; const Target: WideString;
                          const Parameter: WideString): HResult; stdcall;
    function TriggerAction(const Name: WideString): HResult; stdcall;
    function LogMessage(Level: LoggingLevel; const Message: WideString): HResult; stdcall;
    {Declare IMediateInternet methods here}
    function GetHTTPString(const URL: WideString; out Response: WideString): HResult; stdcall;
    function IsConnected(out Connected: WordBool): HResult; stdcall;
    {Declare IMediateApplication methods here}
    function EncodeParams(const Parameters: WideString; out Encoded: WideString): HResult; stdcall;
    function EmbedApplication(const WindowName, WindowClass: WideString;
      WindowLock: WordBool): HResult; stdcall;
    function IsRunning(const ExecutablePath: WideString; out Running: WordBool): HResult; stdcall;
    function LaunchApplication(const ExecutablePath,
      Parameters: WideString): HResult; stdcall;
    function CloseApplication(const ExecutablePath: WideString): HResult;
      stdcall;
    function CloseApplications: HResult; stdcall;
  public
    property InternalName: String read FInternalName write FInternalName;
  end;

implementation

uses ApplicationManager, Languages, Functions, InternetHelper, Utilities,
     Logging;

function TMediateServer.GetAPIVersion(out Version: WideString): HResult;
begin
  Version := 'mediate API v0.1';
  Result := S_OK;
end;

function TMediateServer.GetConfigDirectory(out Directory: WideString): HResult;
begin
  Result := E_FAIL;
  if ApplicationManagerInstance.State <> asInvalid then
  begin
    Directory := ApplicationManagerInstance.ConfigPath;
    Result := S_OK;
  end;
end;

function TMediateServer.GetThemeDirectory(out Directory: WideString): HResult;
begin
  Result := E_FAIL;
  if ApplicationManagerInstance.State <> asInvalid then
  begin
    Directory := ApplicationManagerInstance.ThemePath;
    Result := S_OK;
  end;
end;

function TMediateServer.SubscribeEvent(const Event: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;
  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    ApplicationManagerInstance.PluginManager.SubscribePlugin(FInternalName, Event);
    Result := S_OK;
  end;
end;

function TMediateServer.UnsubscribeEvent(const Event: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;
  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    ApplicationManagerInstance.PluginManager.UnSubscribePlugin(FInternalName, Event);
    Result := S_OK;
  end;
end;

function TMediateServer.GetMetaData(const Name: WideString; out Value: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;
  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    Value := ApplicationManagerInstance.MetaDataManager.GetMetaValue(Name);
    Result := S_OK;
  end;
end;

function TMediateServer.SetMetaData(const Name, Value: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;
  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    FunctionsInstance.SetMeta(Name, Value);
    Result := S_OK;
  end;
end;

function TMediateServer.ClearMetaData(const Name: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;
  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    ApplicationManagerInstance.MetaDataManager.ClearMetaData(Name);
    Result := S_OK;
  end;
end;

function TMediateServer.GetLanguageText(const Name: WideString; out LanguageText: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;
  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    LanguageText := LanguageManagerInstance.Translate(Name);
    Result := S_OK;
  end;
end;

function TMediateServer.CallFunction(const Name, Target, Parameter: WideString): HResult;
var
  MyFunction: TAHMFunction;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    MyFunction := ApplicationManagerInstance.FunctionDescriptor.FunctionList.GetFunction(Name);
    if not Assigned(MyFunction) then Exit;
    if Target = '' then MyFunction.Execute
                   else MyFunction.Execute(Target, Parameter);
    Result := S_OK;
  end;
end;

function TMediateServer.TriggerAction(const Name: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;
  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    ApplicationManagerInstance.ActionManager.ProcessAction(Name);
    Result := S_OK;
  end;
end;

function TMediateServer.LogMessage(Level: LoggingLevel; const Message: WideString): HResult;
begin
  case Level of
    llDebug:   LogDebug(FInternalName + ': ' + Message);
    llInfo:    LogInfo(FInternalName + ': ' + Message);
    llWarning: LogWarn(FInternalName + ': ' + Message);
    llError:   LogError(FInternalName + ': ' + Message);
  end;
  Result := S_OK;
end;


function TMediateServer.GetHTTPString(const URL: WideString; out Response: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    Response := InternetHelperInstance.Get(URL);
    if Response <> '' then Result := S_OK;
  end;
end;

function TMediateServer.IsConnected(out Connected: WordBool): HResult;
begin
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    Connected := InternetHelperInstance.IsConnected;
    Result := S_OK;
  end;
end;

function TMediateServer.EncodeParams(const Parameters: WideString;
  out Encoded: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    Encoded := InternetHelperInstance.EncodeParams(Parameters);
    Result := S_OK;
  end;
end;

function TMediateServer.EmbedApplication(const WindowName,
  WindowClass: WideString; WindowLock: WordBool): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    ApplicationManagerInstance.PluginManager.EmbedPluginApplication(FInternalName, WindowName, WindowClass, WindowLock);
    Result := S_OK;
  end;
end;

function TMediateServer.IsRunning(const ExecutablePath: WideString;
  out Running: WordBool): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    Running := ProcessRunning(ExecutablePath);
    Result := S_OK;
  end;
end;

function TMediateServer.LaunchApplication(const ExecutablePath, Parameters: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering] then
  begin
    ApplicationManagerInstance.PluginManager.LaunchPluginApplication(FInternalName, ExecutablePath, Parameters);
    Result := S_OK;
  end;
end;

function TMediateServer.CloseApplication(const ExecutablePath: WideString): HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering, asClosing] then
  begin
    ApplicationManagerInstance.PluginManager.ClosePluginApplication(FInternalName, ExecutablePath);
    Result := S_OK;
  end;
end;

function TMediateServer.CloseApplications: HResult;
begin
//TODO: make this thread safe
  Result := E_FAIL;

  if ApplicationManagerInstance.State in [asRunning, asRendering, asClosing] then
  begin
    ApplicationManagerInstance.PluginManager.CloseAllPluginApplications(FInternalName);
    Result := S_OK;
  end;
end;

end.
